# -*- coding: utf-8 -*-
# @File     : api.py
# @Author   : bingjia
# @Time     : 2020/8/6 18:54
# @Desc     : 训练api视图

import threading
from django.utils.translation import ugettext_lazy as _
from django.shortcuts import get_list_or_404, get_object_or_404

from operation.base.api import viewsets
from operation.base.api import response
from operation.base.api import exceptions as exc
from operation.base.api.utils.decorators import detail_route
from operation.base.utils.parse_data import parse_data

from . import models
from . import signals
from . import services
from . import validators
from . import serializers
from . import permissions

from .network.yolov5.train_main import train_main


class NetworkAdminViewSet(viewsets.ModelViewSet):
    """
    网络管理视图
    """
    queryset = models.NetworkModel
    "验证"
    validator_class = validators.NetworkValidator
    "序列化"
    serializer_class = serializers.NetworkSerializer
    "权限"
    permission_classes = (permissions.NetworkAdminPermission,)

    def _save_network(self, name, description):
        """
        保存网络模型
        """
        is_exist, reason = services.is_network_already_exist(name)
        if is_exist:
            raise exc.ValidationError(reason)

        network_model = self.queryset

        network = network_model(
            name=name,
            description=description,
        )
        try:
            network.save()
        except Exception as e:
            raise exc.ValidationError(_("uav add failed"))

        signals.uav_registered_signal.send(sender=network.__class__, project=network)

        return network

    def list(self, request, *args, **kwargs):
        """
        群查所有网络
        """
        self.check_permissions(request, 'list', None)

        network_object_list = get_list_or_404(self.queryset)
        if network_object_list:
            page = self.paginate_queryset(network_object_list)
            if page is not None:
                serializer = self.get_serializer(page, many=True)
                return self.get_paginated_response(serializer.data)
            else:
                serializer = self.get_serializer(network_object_list, many=True)

            return response.Ok(serializer.data)
        else:
            return response.Ok({"message": "Have no network"})

    def create(self, request, *args, **kwargs):
        """
        新建网络
        """
        self.check_permissions(request, 'create', None)

        "验证数据"
        try:
            data = parse_data(request.data, cls=validators.NetworkValidator)
            network = self._save_network(**data)
        except exc.ParseError as e:
            raise exc.BadRequest(e.detail)

        serializer = self.get_serializer(network)
        return response.Created(serializer.data)

    def destroy(self, request, *args, **kwargs):
        """
        删除网络
        """
        self.check_permissions(request, 'destroy', None)
        network_obj = get_object_or_404(self.get_queryset())
        network_obj.delete()
        return response.NoContent()

    @detail_route(methods=["POST"])
    def stop(self, request, pk=None):
        """
        暂停训练
        """

    @detail_route(methods=["POST"])
    def restart(self, request, pk=None):
        """
        重置训练

        """


class ModelAdminViewSet(viewsets.ModelViewSet):
    """
    训练管理视图
    """
    queryset = models.ModelInfo
    "验证"
    validator_class = validators.ModelValidator
    "序列化"
    serializer_class = serializers.ModelSerializer
    "权限"
    permission_classes = (permissions.ModelAdminPermission,)

    def _save_model(self, name, description, iterations_number,
                    image_type, category_number, category_info,
                    network_model, models_path):
        """
        保存模型
        """
        is_exist, reason = services.is_model_already_exist(name)
        if is_exist:
            raise exc.ValidationError(reason)

        model_model = self.queryset

        model = model_model(
            name=name,
            description=description,
            iterations_number=iterations_number,
            image_type=image_type,
            category_number=category_number,
            category_info=category_info,
            network_model=models.NetworkModel.objects.get(name=network_model),
            models_path=models_path,
            train_user=self.user
        )
        try:
            model.save()
        except Exception as e:
            raise exc.ValidationError(_("uav add failed"))

        signals.model_registered_signal.send(sender=model.__class__, project=model)

        return model

    def list(self, request, *args, **kwargs):
        """
        群查所有训练
        """
        self.check_permissions(request, 'list', None)

        model_object_list = get_list_or_404(self.queryset)
        if model_object_list:
            page = self.paginate_queryset(model_object_list)
            if page is not None:
                serializer = self.get_serializer(page, many=True)
                return self.get_paginated_response(serializer.data)
            else:
                serializer = self.get_serializer(model_object_list, many=True)

            return response.Ok(serializer.data)
        else:
            return response.Ok({"message": "Have no model"})

    def create(self, request, *args, **kwargs):
        """
        新建训练
        """
        self.user = request.user
        self.check_permissions(request, 'create', None)

        "创建训练线程"
        train_threading = threading.Thread(target=train_main(), args=())
        train_threading.start()

        print("开始训练....")

        "验证数据"
        # try:
        #     data = parse_data(request.data, cls=validators.NetworkValidator)
        #     model = self._save_model(**data)
        # except exc.ParseError as e:
        #     raise exc.BadRequest(e.detail)

        # serializer = self.get_serializer(model)
        # return response.Created(serializer.data)

        return response.Ok({"message":"start train !!!"})

    def destroy(self, request, *args, **kwargs):
        """
        删除模型
        """
        self.check_permissions(request, 'destroy', None)
        model_obj = get_object_or_404(self.get_queryset())
        model_obj.delete()
        return response.NoContent()

    @detail_route(methods=["POST"])
    def stop(self, request, pk=None):
        """
        暂停训练
        """

    @detail_route(methods=["POST"])
    def restart(self, request, pk=None):
        """
        重置训练
        """
